Realisatiefase PostcodeApp
Home

Realisatiefase PostcodeApp

Realisatiefase PostcodeApp

In de realisatiefase begint men aan het bouwen van het projectresultaat en wordt het project zichtbaar. Programmeurs zijn aan het coderen, designers zijn bezig beeldmateriaal te ontwikkelen, ... Voor de buitenstaanders lijkt het alsof het project nu pas gestart is. Het is de ‘doe’ fase.

Realisatiefase

  1. Nadat je alle mappen en bestanden in deze les hebt gemaakt, de klassen hebt toegevoegd en de app hebt uitgevoerd, ziet de bestandstructuur van je project er zo uit:
    Visual Studio Directory Structure PostcodeApp
    Visual Studio Directory Structure PostcodeApp
    1. Map voor Business Logic Layer
    2. Map voor data storage
    3. Map voor Data Access Layer
    4. Helpers map
    5. Map voor presentation layer
  2. Maak een nieuw .NET Core console project met de naam PostcodeApp en de map dotnetcore:
    Visual Studio Nieuw project PostcodeApp
    Visual Studio Nieuw project PostcodeApp

    Visual Studio 2019:

    Visual Studio 2019  Nieuw project PostcodeApp
    Visual Studio 2019 Nieuw project PostcodeApp
    1. C# project
    2. Een Console App in .NET Core
    3. in de map dotnetcore van Programmeren3
    4. de naam van het project is PostcodeApp
    5. vink het vakje Create directory for solution niet aan / in 2019 wel aanvinken
    6. ok
  3. Maak de mappen om de n-tier architectuur te implementeren:
    Visual Studio Directory Structure N-tier PostcodeApp
    Visual Studio Directory Structure N-tier PostcodeApp
    1. Bll voor business logic layer
    2. Dal voor data access layer
    3. Pl voor presentation layer
  4. We hebben de volgende packages nodig. Open de Package Manager Console:
    Visual Studio Open Package Manager Console
    Visual Studio Open Package Manager Console
  5. Zorg ervoor dat je de laatste versies installeert.
    1. System.Xml.XmlSerializer
      PM>Install-Package System.Xml.XmlSerializer -Version 4.3.0
    2. Newtonsoft.Json
      PM>Install-Package Newtonsoft.Json -Version 12.0.3
      
  6. Het PostcodeApp.csproj bestand ziet er nu zo uit (om dit bestand te openen klik je met de rechtermuisknop op de naam van het project en selecteer je Edit PostcodeApp.csproj:
    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <Folder Include="Bll\" />
        <Folder Include="Dal\" />
        <Folder Include="Pl\" />
      </ItemGroup>
    
      <ItemGroup>
        <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
        <PackageReference Include="System.Xml.XmlSerializer" Version="4.3.0" />
      </ItemGroup>
    
    </Project>
    
    
  7. De BLL maken (voor de benaming van namespaces, methoden, eigenschappen zie: Ontwerpfase PostcodeApp):

    1. Maak een klassenbestand in de map /Bll met de naam Postcode.cs.
    2. Als namespace gebruik je de naam PostcodeApp.Bll.
    3. De naam van de klasse is Postcode.
    4. Voeg de getters en setters toe. Deze eigenschappen doen niet veel, maar later voegen we daar business logic aan toe:
      using System.Collections.Generic;
      
      namespace PostcodeApp.Bll
      {
          public class Postcode
          {
              private string code;
              public string Code
              {
                  get { return code; }
                  set { code = value; }
              }
      
              private string plaats;
              public string Plaats
              {
                  get { return plaats; }
                  set { plaats = value; }
              }
      
              private string provincie;
              public string Provincie
              {
                  get { return provincie; }
                  set { provincie = value; }
              }
      
              private string localite;
              public string Localite
              {
                  get { return localite; }
                  set { localite = value; }
              }
      
              private string province;
              public string Province
              {
                  get { return province; }
                  set { province = value; }
              }
      
              private List<Postcode> list;
              public List<Postcode> List
              {
                  get { return list; }
                  set { list = value; }
              }
          }
      }
  8. De DAL voor een CSV bestand maken (voor de benaming van namespaces, methoden, eigenschappen zie: Ontwerpfase PostcodeApp)
    1. Kopieer het klassenbestand Tekstbestand.cs uit Tekstbestanden inlezen en plaats het in de map /Helpers.
    2. Maak de /Data map in Programmeren3\PostcodeApp\bin\Debug\netcoreapp3.1. Ter herinnering als je een programma in debug modus uitvoert wordt een exe bestand gemaakt. Die staat op mijn computer in de volgende submap:
      Visual Studio map waar exe bestand staat in debug modus
      Visual Studio map waar exe bestand staat in debug modus
    3. Kopieer de volgende bestanden in de /Data map:
      1. Postcode.json
      2. Postcode.csv
      3. Postcode.xml
    4. Voor elke opslagmethode, CSV, XML en JSON hebben we een aparte klasse nodig. Maar alle drie de klassen moeten over dezelfde eigenschappen en methoden beschikken. Dat is dus bij uitstek een ideale omstandigheid om een interface te maken (meer over interfaces: interface (C# Reference)). Maak een bestand in de map /Dal met de naam IPostcode.cs. Gebruik de namespace PostcodeApp.Dal en als interface-naam IPostcode:
      namespace PostcodeApp.Dal
      {
          public interface IPostcode
          {
              // Property signatures:
              // Een Postcode BLL object om de opgehaalde waarden
              // in op te slagen
              Bll.Postcode Postcode { get; set; }
              // Error message
              string Message { get; set; }
              string ConnectionString { get; set; }
              // method signatures
              bool Create();
              bool ReadAll();
          }
      }
      
    5. De DAL klasse voor CSV bestanden (PostcodeCsv.cs):
      using System;
      using System.Collections.Generic;
      using System.IO;
      
      namespace PostcodeApp.Dal
      {
          class PostcodeCsv : IPostcode
          {
              // Een Postcode BLL object om de opgehaalde waarden
              // in op te slagen
              public Bll.Postcode Postcode { get; set; }
              // Error message
              public string Message { get; set; }
              private string connectionString = @"Data/Postcode";
              public string ConnectionString
              {
                  get
                  {
                      return connectionString + ".csv";
                  }
                  set
                  {
                      connectionString = value;
                  }
              }
      
              public char Separator { get; set; } = ';';
      
              public PostcodeCsv(Bll.Postcode postcode)
              {
                  Postcode = postcode;
              }
      
              public bool ReadAll()
              {
                  Helpers.Tekstbestand bestand = new Helpers.Tekstbestand();
                  bestand.FileName = ConnectionString;
                  if (bestand.Lees())
                  {
                     string[] postcodes = bestand.Text.Split('\n');
                      try
                      {
                          List<Bll.Postcode> list = new List<Bll.Postcode>();
                          foreach (string s in postcodes)
                          {
                              if (s.Length > 0)
                              {
                                   list.Add(ToObject(s));
                              }
                          }
                          Postcode.List = list;
                          Message = $"Het bestand {ConnectionString} is gedesialiseerd!";
                          return true;
                      }
                      catch (Exception e)
                      {
                          // Melding aan de gebruiker dat iets verkeerd gelopen is.
                          // We gebruiken hier de nieuwe mogelijkheid van C# 6: string interpolatie
                          Message = $"Bestand {ConnectionString} is niet gedeserialiseerd.\nFoutmelding {e.Message}.";
                          return false;
                      }
                  }
                  else
                  {
                      Message = $"Bestand {ConnectionString} is niet gedeserialiseerd.\nFoutmelding {bestand.Melding}.";
                      return false;
                  }
              }
      
              private Bll.Postcode ToObject(string line)
              {
                  Bll.Postcode postcode = new Bll.Postcode();
                  string[] values = line.Split(Separator);
                  postcode.Code = values[0];
                  postcode.Plaats = values[1];
                  postcode.Provincie = values[2];
                  postcode.Localite = values[3];
                  postcode.Province = values[4];
                  return postcode;
              }
      
              /// <summary>
              /// De Create van CRUD
              /// In het geval van een CSV bestand wordt de hele List gecreëerd.
              /// </summary>
              /// <returns></returns>
              public bool Create()
              {
                   try
                  {
                      TextWriter writer = new StreamWriter(ConnectionString);
                      foreach (Bll.Postcode item in Postcode.List)
                      {
                          // One of the most versatile and useful additions to the C# language in version 6
                          // is the null conditional operator ?.Post           
                          writer.WriteLine("{0}{5}{1}{5}{2}{5}{3}{5}{4}",
                              item?.Code,
                              item?.Plaats,
                              item?.Provincie,
                              item?.Localite,
                              item?.Province,
                              Separator);
                      }
                      writer.Close();
                      Message = $"Het bestand met de naam {ConnectionString} is gemaakt!";
                      return true;
                  }
                  catch (Exception e)
                  {
                      // Melding aan de gebruiker dat iets verkeerd gelopen is.
                      // We gebruiken hier de nieuwe mogelijkheid van C# 6: string interpolatie
                      Message = $"Bestand met naam {ConnectionString} niet gemaakt.\nFoutmelding {e.Message}.";
                      return false;
                  }
               }
      
              // Een overload om tegelijkertijd de separator in te stellen
              public bool Create(char separator = ';')
              {
                  Separator = separator;
                  return Create();
              }
          }
      }
    6. DAL klasse voor XML bestand:
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Xml.Serialization;
      
      namespace PostcodeApp.Dal
      {
          class PostcodeXml : IPostcode
          {
              // Een Postcode BLL object om de opgehaalde waarden
              // in op te slagen
              public Bll.Postcode Postcode { get; set; }
              // Error message
              public string Message { get; set; }
              private string connectionString = @"Data/Postcode";
              public string ConnectionString
              {
                  get
                  {
                      return connectionString + ".xml";
                  }
                  set
                  {
                      connectionString = value;
                  }
              }
              public PostcodeXml(Bll.Postcode postcode)
              {
                  Postcode = postcode;
              }
      
              // een overload om de naam van het csv bestand in te stellen
              public PostcodeXml(string connectionString)
              {
                  ConnectionString = connectionString;
              }
      
              /// <summary>
              /// In het geval van XML wordt heel de List gesaved.
              /// </summary>
              /// <returns></returns>
              public bool Create()
              {
                  try
                  {
                      XmlSerializer serializer = new XmlSerializer(typeof(Bll.Postcode[]));
                      TextWriter writer = new StreamWriter(ConnectionString);
                      //De serializer werkt niet voor een generieke lijst en ook niet voor ArrayList
                      // dus eerst omzetten naar array
                      Bll.Postcode[] postcodes = Postcode.List.ToArray();
                      serializer.Serialize(writer, postcodes);
                      writer.Close();
                      Message = $"Bestand {ConnectionString} is met succes geserialiseerd.";
                      return true;
                  }
                  catch (Exception e)
                  {
                      // Melding aan de gebruiker dat iets verkeerd gelopen is.
                      // We gebruiken hier de nieuwe mogelijkheid van C# 6: string interpolatie
                      Message = $"Bestand {ConnectionString} is niet geserialiseerd.\nFoutmelding {e.Message}.";
                      return false;
                  }
              }
      
              public bool ReadAll()
              {
                  try
                  {
                      XmlSerializer serializer = new XmlSerializer(typeof(Bll.Postcode[]));
                      StreamReader file = new System.IO.StreamReader(ConnectionString);
                      Bll.Postcode[] postcodes = (Bll.Postcode[])serializer.Deserialize(file);
                      file.Close();
                      // array converteren naar List
                      Postcode.List = new List<Bll.Postcode>(postcodes);
                      Message = $"Bestand {ConnectionString} is met succes gedeserialiseerd.";
                      return true;
                  }
                  catch (Exception e)
                  {
                      // Melding aan de gebruiker dat iets verkeerd gelopen is.
                      // We gebruiken hier de nieuwe mogelijkheid van C# 6: string interpolatie
                      Message = $"Het bestand {ConnectionString} s niet gedeserialiseerd.\nFoutmelding {e.Message}.";
                      return false;
                  }
      
              }
          }
      }
    7. De DAL klasse voor het JSON bestand:
      using System;
      using System.Collections.Generic;
      using System.IO;
      
      namespace PostcodeApp.Dal
      {
          class PostcodeJson : IPostcode
          {
              // Een Postcode BLL object om de opgehaalde waarden
              // in op te slagen
              public Bll.Postcode Postcode { get; set; }
               // Error message
              public string Message { get; set; }
              private string connectionString = @"Data/Postcode";
              public string ConnectionString
              {
                  get
                  {
                      return connectionString + ".json";
                  }
                  set
                  {
                      connectionString = value;
                  }
              }
              public PostcodeJson(Bll.Postcode postcode)
              {
                  Postcode = postcode;
              }
      
              // een overload om de naam van het csv bestand in te stellen
              public PostcodeJson(string connectionString)
              {
                  ConnectionString = connectionString;
              }
              /// <summary>
              /// In het geval van JSON wordt heel de List gesaved
              /// </summary>
              public bool Create()
              {
                  try
                  {
                      TextWriter writer = new StreamWriter(ConnectionString);
                      // static method SerilizeObject van Newtonsoft.Json
                      string postcodeString = Newtonsoft.Json.JsonConvert.SerializeObject(Postcode.List);
                      writer.WriteLine(postcodeString);
                      writer.Close();
                      Message = $"Het bestand met de naam {ConnectionString} is met succes geserialiseerd.";
                      return true;
                  }
                  catch (Exception e)
                  {
                      // Melding aan de gebruiker dat iets verkeerd gelopen is.
                      // We gebruiken hier de nieuwe mogelijkheid van C# 6: string interpolatie
                      Message = $"Kan het bestand met de naam {ConnectionString} niet serialiseren.\nFoutmelding {e.Message}.";
                      return false;
                  }
              }
       
              public bool ReadAll()
              {
                  try
                  {
                      Helpers.Tekstbestand bestand = new Helpers.Tekstbestand();
                      bestand.FileName = ConnectionString;
                      bestand.Lees();
                      Postcode.List = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Bll.Postcode>>(bestand.Text);
                      Message = $"Het bestand met de naam {ConnectionString} is met succes geserialiseerd.";
                      return true;
                  }
                  catch (Exception e)
                  {
                      // Melding aan de gebruiker dat iets verkeerd gelopen is.
                      // We gebruiken hier de nieuwe mogelijkheid van C# 6: string interpolatie
                      Message = $"Kan het bestand met de naam {ConnectionString} niet deserialiseren.\nFoutmelding {e.Message}.";
                      return false;
                  }
      
              }
          }
      }
  9. De presentatielaag voor de console staat in het bestand PostcodeConsole.cs in de Pl map, in de klasse met de naam PostcodeConsole in de namespace met de naam PostcodeApp.View. De view bevat de logica om de data op het scherm te tonen. In dit geval is dat Console.WriteLine. En model bevat de data die in de view getoond worden. In de Postcode App is dat het Bll object:
    using System;
    
    namespace PostcodeApp.View
    {
        class PostcodeConsole
        {
            public Bll.Postcode Model { get; set; }
    
            public PostcodeConsole(Bll.Postcode postcode)
            {
                Model = postcode;
            }
    
            public void List(Bll.Postcode postcode)
            {
                Model = postcode;
            }
    
            public void List()
            {
                foreach (Bll.Postcode postcode in Model.List)
                {
                    // One of the most versatile and useful additions to the C# language in version 6
                    // is the null conditional operator ?.Post           
                    Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}",
                        postcode?.Code,
                        postcode?.Plaats,
                        postcode?.Provincie,
                        postcode?.Localite,
                        postcode?.Province);
                }
            }
        }
    }
    
  10. Tenslotte proberen we de verschillende klassen uit in de Program klasse, die staat in het Program.cs bestand:
    using System;
    
    namespace PostcodeApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                TryOutCsv();
                TryOutXml();
                TryOutJson();
                Console.ReadLine();
            }
    
            static void TryOutCsv()
            {
                Console.WriteLine("De Postcode App CSV");
                Bll.Postcode postcode = new Bll.Postcode();
                Dal.PostcodeCsv postcodeCsv = new Dal.PostcodeCsv(postcode);
                // de seperator staat standaard op ;
                // in het Postcode.csv bestand is dat |
                postcodeCsv.Separator = ';';
                postcodeCsv.Postcode = postcode;
                postcodeCsv.ReadAll();
                Console.WriteLine(postcodeCsv.Message);
                View.PostcodeConsole view = new View.PostcodeConsole(postcode);
                view.List();
                // serialize postcodes met een andere separator
                // naar ander bestand
                postcodeCsv.ConnectionString = "Data/Postcode2";
                postcodeCsv.Create(';');
                Console.WriteLine(postcodeCsv.Message);
            }
    
            static void TryOutXml()
            {
                Console.WriteLine("De Postcode App XML");
                Bll.Postcode postcode = new Bll.Postcode();
                Dal.PostcodeXml postcodeXml = new Dal.PostcodeXml(postcode);
                postcodeXml.Postcode = postcode;
                postcodeXml.ReadAll();
                Console.WriteLine(postcodeXml.Message);
                View.PostcodeConsole view = new View.PostcodeConsole(postcode);
                view.List();
                // serialize naar ander bestand
                postcodeXml.FileName = "Data/Postcode2.xml";
                postcodeXml.Create();
                Console.WriteLine(postcodeXml.Message);
            }
    
            static void TryOutJson()
            {
                Console.WriteLine("De Postcode App Json");
                Bll.Postcode postcode = new Bll.Postcode();
                Dal.PostcodeJson postcodeJson = new Dal.PostcodeJson(postcode);
                postcodeJson.Postcode = postcode;
                postcodeJson.ReadAll();
                Console.WriteLine(postcodeJson.Message);
                View.PostcodeConsole view = new View.PostcodeConsole(postcode);
                view.List();
                // serialize naar ander bestand
                postcodeJson.FileName = "Data/Postcode2.json";
                postcodeJson.Create();
                Console.WriteLine(postcodeJson.Message);
            }
        }
    }
    
    

JI
2020-10-12 16:37:03